package test.designmode.producerconsumer;

import java.util.concurrent.*;

/**
 * 生产者-消费者模型:
 *      1. 生产者消费者均实现了runnable;
 *      2. 生产者消费者共用一条队列,通过构造传入;
 *      3. 生产者消费者的run里面都是死循环,一个负责往队列丢东西,一个负责从队列里取东西;
 *      4. 多个生产者多个消费者(多条线程);
 */
public class Main {
    public static void main(String[] args) throws InterruptedException {
        /* 队列的本质就是内存缓冲的实现之一 */
        BlockingQueue<Data> queue = new LinkedBlockingQueue<>();
        /* 生产者 */
        Producer producer1 = new Producer(queue);
        Producer producer2 = new Producer(queue);
        Producer producer3 = new Producer(queue);
        Producer producer4 = new Producer(queue);
        /* 消费者 */
        Consumer consumer1 = new Consumer(queue);
        Consumer consumer2 = new Consumer(queue);
        Consumer consumer3 = new Consumer(queue);
        Consumer consumer4 = new Consumer(queue);
        /* 创建线程池运行,这是一个缓存的线程池，可以创建无穷大的线程，没有任务的时候不创建线程。空闲线程存活时间为60s（默认值）
         * (但无穷大不一定是好事, 在高并发情况下可能耗尽资源导致oom, 但不会stackOverFlow, SOF一般是因为递归)
         * */
        /* ExecutorService线程池: https://www.cnblogs.com/Steven0805/p/6393443.html */
        ExecutorService cachePool = Executors.newCachedThreadPool();
        cachePool.execute(producer1);
        cachePool.execute(producer2);
        cachePool.execute(producer3);
        cachePool.execute(producer4);
        cachePool.execute(consumer1);
        cachePool.execute(consumer2);
        cachePool.execute(consumer3);
        cachePool.execute(consumer4);

        Thread.sleep(5000);
        /* 停止生产 */
        producer1.stop();
        producer2.stop();
        producer3.stop();
        producer4.stop();
        cachePool.shutdown();
        cachePool.shutdownNow();

    }
}
